<!--
 * Copyright © 2023
 * @Author: zhangxiang
 * @Date: 2023-05-11 16:13:15
 * @LastEditors: zhangxiang
 * @LastEditTime: 2023-05-11 16:44:53
 * @Description:
 *
-->

<template>
  <div class="alarm-overview-container">
    <div class="chart">
      <el-row type="flex" justify="space-between" align="middle">
        <div class="title">告警统计</div>
        <el-radio-group
          v-model="chartTimeType"
          size="small"
          @change="chartTimeTypeChange"
        >
          <el-radio-button label="24hour">近24小时</el-radio-button>
          <el-radio-button label="7day">近一周</el-radio-button>
        </el-radio-group>
      </el-row>
      <div id="chart-bar"></div>
    </div>
    <div class="main">
      <el-row type="flex" align="middle">
        <span class="name">告警名称</span>
        <el-input
          v-model="ruleName"
          style="width: 170px; margin-left: 10px; margin-right: 20px"
          size="medium"
          class="input"
          placeholder="请输入告警名称"
          clearable
          @clear="clearNameClick('ruleName')"
          @keyup.enter.native="queryClick"
        />
        <span class="name">级别</span>
        <el-select
          v-model="alarmLevel"
          placeholder="请选择告警级别"
          size="medium"
          style="width: 170px; margin-left: 10px; margin-right: 20px"
        >
          <el-option
            v-for="item in levelOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <span class="name">资源名称</span>
        <el-input
          v-model="resourceName"
          style="width: 170px; margin-left: 10px; margin-right: 20px"
          size="medium"
          class="input"
          placeholder="请输入资源名称"
          clearable
          @clear="clearNameClick('resourceName')"
          @keyup.enter.native="queryClick"
        />
        <el-button
          size="medium"
          type="primary"
          @click="queryClick"
        >查询</el-button>
        <el-button size="medium" @click="resetClick">重置</el-button>
        <el-button
          size="medium"
          type="primary"
          style="margin-left: auto"
          :loading="exportLoading"
          @click="exportClick"
        >导出</el-button>
      </el-row>
      <div class="line"></div>
      <el-table
        v-loading="loading"
        :data="list"
        header-cell-class-name="listHeaderCell"
        :header-cell-style="{ background: '#F3F3F3', color: '#696969' }"
      >
        <el-table-column prop="ruleName" label="告警名称" min-width="170" />
        <el-table-column prop="alarmLevel" label="级别" min-width="150">
          <template slot-scope="scope">
            <div
              v-if="scope.row.alarmLevel === '紧急'"
              class="alarmLevel level1"
            >
              {{ scope.row.alarmLevel }}
            </div>
            <div
              v-else-if="scope.row.alarmLevel === '重要'"
              class="alarmLevel level2"
            >
              {{ scope.row.alarmLevel }}
            </div>
            <div
              v-else-if="scope.row.alarmLevel === '次要'"
              class="alarmLevel level3"
            >
              {{ scope.row.alarmLevel }}
            </div>
            <div
              v-else-if="scope.row.alarmLevel === '提示'"
              class="alarmLevel level4"
            >
              {{ scope.row.alarmLevel }}
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="resourceType" label="资源类型" min-width="170" />
        <el-table-column prop="resourceName" label="资源名称" min-width="170" />
        <el-table-column
          prop="detailMsg"
          label="详细信息"
          min-width="170"
          show-overflow-tooltip=""
        />
        <el-table-column prop="createTime" label="产生时间" min-width="170" />
        <el-table-column label="操作" width="100" fixed="right">
          <template slot-scope="scope">
            <el-popover
              :ref="`popover-delete-${scope.$index}`"
              placement="top"
              width="300"
            >
              <p>是否确认删除该记录？</p>
              <div style="text-align: right; margin: 0">
                <el-button
                  size="mini"
                  type="text"
                  @click="
                    scope._self.$refs[
                      `popover-delete-${scope.$index}`
                    ].doClose()
                  "
                >取消</el-button>
                <el-button
                  type="primary"
                  size="mini"
                  @click="deleteClick(scope)"
                >确定</el-button>
              </div>
              <el-button
                slot="reference"
                type="danger"
                style="height: 22px; line-height: 22px; padding: 0 10px"
                size="mini"
              >清除</el-button>
            </el-popover>
          </template>
        </el-table-column>
      </el-table>
      <el-row type="flex" justify="end" style="margin-top: 20px">
        <el-pagination
          background
          layout="total, sizes, prev, pager, next"
          :page-sizes="[10, 15, 20]"
          :page-size="pageSize"
          :current-page.sync="pageNum"
          :total="totalSize"
          @current-change="changePage"
          @size-change="sizeChange"
        />
      </el-row>
    </div>
  </div>
</template>

<script>
import { ALARM_LEVEL } from '@/utils/cnap/constant'
import {
  getAlarmList,
  deleteAlarm,
  getAlarmChart,
  getAlarmExport
} from '@/api/cnap/statis-analysis'
import { parseTime } from '@/utils/utils'
import * as echarts from 'echarts'

export default {
  name: 'AlarmOverview',
  components: {},
  data() {
    return {
      levelOptions: ALARM_LEVEL, // 级别选项
      ruleName: '', // 告警名称
      alarmLevel: '', // 告警级别
      resourceName: '', // 资源名称
      loading: false, // 加载中
      pageSize: 10, // 页大小
      pageNum: 1, // 页码
      totalSize: 0, // 总数
      list: [], // 列表数据
      chartTimeType: '24hour', // 图表筛选时间
      totalStatistic: {},
      chartData: [], // 图表数据
      chart: null, // 图表
      exportLoading: false // 导出loading
    }
  },
  computed: {
    /**
     * @description: 横坐标
     * @return {*}
     */
    xAxisData() {
      const xdata = []
      // 循环遍历
      for (const item of this.chartData) {
        const date = parseTime(item.timestamp, '{m}/{d} {h}:{i}') // 格式化时间
        xdata.push(date)
      }
      return xdata
    },
    /**
     * @description: 数据
     * @return {*}
     */
    seriesData() {
      const prompt = [] // 初始化提示
      const minor = [] // 初始化次要
      const major = [] // 初始化主要
      const emergency = [] // 初始化紧急
      // 循环遍历
      for (const item of this.chartData) {
        if (item.alarmStatistic) {
          // 组装数据
          prompt.push(item.alarmStatistic.prompt || 0) // 提示
          minor.push(item.alarmStatistic.minor || 0) // 次要
          major.push(item.alarmStatistic.major || 0) // 主要
          emergency.push(item.alarmStatistic.emergency || 0) // 紧急
        }
      }
      const setting = {
        // 样式配置
        type: 'bar', // 类型
        barWidth: 28, // 宽度
        stack: 'total', // 堆叠
        emphasis: {
          focus: 'series'
        }
      }
      return [
        {
          name: '提示',
          ...setting, // 展示配置
          data: prompt
        },
        {
          name: '次要',
          ...setting, // 展示配置
          data: minor
        },
        {
          name: '重要',
          ...setting, // 展示配置
          data: major
        },
        {
          name: '紧急',
          ...setting, // 展示配置
          data: emergency
        }
      ]
    }
  },
  created() {
    this.initPageData() // 初始化数据
  },
  methods: {
    /**
     * @description: 导出
     * @return {*}
     */
    exportClick() {
      this.exportLoading = true // 展示导出loading
      // 请求
      getAlarmExport({
        alarmLevel: this.alarmLevel
      })
        .then((response) => {
          const fileNames =
            response.headers['content-disposition'].split("filename*=utf-8''") // 读取文件名
          const fileName =
            fileNames.length > 1
              ? decodeURIComponent(fileNames[1])
              : '事件详情.xlsx' // 解析文件名
          const blob = new Blob([response.data], {
            type: 'application/vnd.ms-excel'
          }) // 新建blob
          const elementA = document.createElement('a') // 创建 element a
          elementA.style.display = 'none' // 设置不可见
          elementA.href = window.URL.createObjectURL(blob) // 设置href
          elementA.download = fileName // 设置名称
          document.body.appendChild(elementA) // 添加到body
          elementA.click() // 模拟点击
          window.URL.revokeObjectURL(elementA.href) // 释放内存
        })
        .catch((err) => {
          console.log(err)
          this.$message.error('导出失败，请稍候再试') // 导出失败
        })
        .finally(() => {
          this.exportLoading = false // 取消loading
        })
    },
    /**
     * @description: 设置图表数据
     * @return {*}
     */
    setChart() {
      if (!this.chart) {
        this.chart = echarts.init(document.getElementById('chart-bar')) // 初始化
      }
      this.chart.setOption({
        color: ['#0091FF', '#6DD400', '#f7b500', '#E8525B'], // 颜色
        tooltip: {
          trigger: 'axis', // 触发类型
          axisPointer: {
            type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
          },
          confine: true
        },
        legend: {
          // 图例
          itemGap: 20, // 间距
          icon: 'circle', // 样式
          itemWidth: 14, // 宽度
          itemHeight: 14, // 高度
          // 格式化文字
          formatter: (name) => {
            if (name === '提示') {
              return name + ' ' + this.totalStatistic.prompt
            } else if (name === '次要') {
              return name + ' ' + this.totalStatistic.minor
            } else if (name === '重要') {
              return name + ' ' + this.totalStatistic.major
            } else if (name === '紧急') {
              return name + ' ' + this.totalStatistic.emergency
            }
            return name
          },
          textStyle: {
            // 文字样式
            color: '#696969', // 颜色
            height: 10, // 高度
            rich: {
              a: {
                verticalAlign: 'middle' // 居中
              }
            }
          }
        },
        grid: {
          left: '0',
          right: '5',
          bottom: '0',
          containLabel: true
        },
        xAxis: {
          // 横坐标配置
          type: 'category',
          axisTick: {
            // tick样式
            show: false // 不显示
          },
          axisLabel: {
            // 文本样式
            show: true, // 显示
            color: '#C3C3C3' // 颜色
          },
          axisLine: {
            // 线条样式
            show: true, // 显示
            lineStyle: {
              color: '#EAEAEA' // 颜色
            }
          },
          data: this.xAxisData
        },
        yAxis: {
          type: 'value',
          axisLine: {
            // 线条样式
            show: false // 不显示
          },
          axisLabel: {
            // 文本样式
            show: true, // 显示
            color: '#C3C3C3' // 颜色
          },
          splitLine: {
            // 分割线样式
            show: true, // 显示
            lineStyle: {
              color: '#EAEAEA', // 颜色
              type: 'dashed' // 类型
            }
          },
          axisTick: {
            // tick样式
            show: false // 不显示
          }
        },
        series: this.seriesData
      })
    },
    /**
     * @description: 图标数据分类切换
     * @return {*}
     */
    chartTimeTypeChange(val) {
      this.getAlarmChartData() // 请求数据
    },
    /**
     * @description: 获取告警统计
     * @return {*}
     */
    getAlarmChartData() {
      // 请求
      getAlarmChart(this.chartTimeType)
        .then((res) => {
          this.totalStatistic =
            res.data && res.data.totalStatistic
              ? res.data.totalStatistic
              : { emergency: 0, major: 0, minor: 0, prompt: 0 }
          this.chartData =
            res.data && Array.isArray(res.data.data) ? res.data.data : []
          if (this.chartData.length > 0) {
            this.setChart() // 设置图表
          }
        })
        .catch(() => {
          this.chartData = []
        })
    },
    /**
     * @description: 清除
     * @param {*} scope
     * @return {*}
     */
    deleteClick(scope) {
      const row = scope.row
      // 请求接口
      deleteAlarm(row.id).then((res) => {
        scope._self.$refs[`popover-delete-${scope.$index}`].doClose() // 取消popover
        this.$message.success('清除成功')
        if (this.list.length === 1) {
          this.pageNum = Math.max(this.pageNum - 1, 1) // 当前页只剩一条数据时 删除后请求上一页
        }
        this.getAlarmList() // 请求数据
      })
    },
    /**
     * @description: size变化
     * @param {*} size
     * @return {*}
     */
    sizeChange(size) {
      this.pageSize = size
      this.pageNum = 1 // 第一页
      this.getAlarmList() // 请求数据
    },
    /**
     * @description: 切换页码
     * @param {*} pageNum
     * @return {*}
     */
    changePage(pageNum) {
      this.pageNum = pageNum
      this.getAlarmList() // 请求数据
    },
    /**
     * @description: 清除名称
     * @return {*}
     */
    clearNameClick(name) {
      if (name === 'ruleName') {
        // 告警名称
        this.ruleName = ''
      } else if (name === 'resourceName') {
        // 资源名称
        this.resourceName = ''
      }
      this.pageNum = 1 // 第一页
      this.getAlarmList() // 请求数据
    },
    /**
     * @description: 重置
     * @return {*}
     */
    resetClick() {
      this.ruleName = ''
      this.resourceName = ''
      this.alarmLevel = ''
      this.pageNum = 1 // 第一页
      this.getAlarmList() // 请求数据
    },
    /**
     * @description: 查询
     * @return {*}
     */
    queryClick() {
      this.pageNum = 1
      this.getAlarmList() // 请求数据
    },
    /**
     * @description: 获取告警列表
     * @return {*}
     */
    getAlarmList() {
      // 请求
      getAlarmList({
        ruleName: this.ruleName, // 告警名称
        resourceName: this.resourceName, // 资源名称
        alarmLevel: this.alarmLevel, // 级别
        pageNum: this.pageNum, // 页码
        pageSize: this.pageSize // 页size
      })
        .then((res) => {
          if (res.data) {
            this.totalSize = res.data.totalSize
            this.list = Array.isArray(res.data.data) ? res.data.data : []
          } else {
            // 数据为空处理
            this.totalSize = 0
            this.list = []
          }
        })
        .finally(() => {
          this.loading = false // 取消loading
        })
    },
    /**
     * @description: 初始化数据
     * @return {*}
     */
    initPageData() {
      this.loading = true
      this.pageNum = 1
      this.getAlarmList() // 请求告警列表
      this.getAlarmChartData() // 请求告警统计表数据
    }
  }
}
</script>

<style lang="less" scoped>
@import "@/assets/css/common.less";
.alarm-overview-container {
  .chart {
    margin-bottom: 20px;
    height: 280px;
    box-sizing: border-box;
    background: #fdfdfd;
    border: 1px solid #ececec;
    padding: 10px 20px;

    .title {
      .textStyle(14px , 500, #262626);
      line-height: 24px;
    }
    #chart-bar {
      margin-top: 2px;
      width: 100%;
      height: 210px;
      overflow: hidden;
    }
  }

  .main {
    background: #fdfdfd;
    border: 1px solid #ececec;
    padding: 10px 20px;
    .name {
      .textStyle(14px , 400, #4a4a4a);
      line-height: 20px;
    }

    .line {
      margin: 20px 0;
      height: 1px;
      background-color: #f2f2f2;
    }

    .alarmLevel {
      box-sizing: border-box;
      width: 52px;
      height: 22px;
      border-radius: 11px;
      border: 1px solid #f66173;
      background: rgba(255, 185, 189, 0.7);
      text-align: center;
      line-height: 22px;
      .textStyle(12px , 500, #E8525B);

      &.level2 {
        background-color: #fff3d2;
        border-color: #f7b500;
        color: #f7b500;
      }
      &.level3 {
        background-color: #e8f9d6;
        border-color: #6dd400;
        color: #6dd400;
      }
      &.level4 {
        background-color: #e1f2ff;
        border-color: #0091ff;
        color: #0091ff;
      }
    }

    .el-table::before {
      background-color: #e9e9e9;
    }
    /deep/ .listHeaderCell {
      height: 40px;
      padding: 0;
      box-sizing: border-box;
      &:first-child {
        padding-left: 20px;
      }
    }

    /deep/ .el-table__body {
      .el-table__row td {
        height: 40px;
        padding: 0;
        &:first-child {
          padding-left: 20px;
        }
      }
    }
  }
}
</style>
